package com.topcheer.common.base.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.topcheer.common.base.mapper.Mapper;
import com.topcheer.common.base.service.BaseService;
import com.topcheer.common.base.util.EntityUtils;
import com.topcheer.common.base.vo.PageVo;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xutao
 * @Package com.topcheer.common.base.service.impl
 * @Description: ${todo}
 * @date 2020/3/29 20:42
 */
public class BaseBiz<M extends Mapper<T>, T> implements BaseService<T>, ApplicationListener<ContextRefreshedEvent> {
    public Map<String, String> columnMapping = new ConcurrentHashMap<String, String>();
    @Autowired
    protected M mapper;
    @Autowired
    SqlSessionFactory sqlSessionFactory;

    @Override
    public T selectOne(Object id) {
        return mapper.selectOne(id);
    }

    @Override
    public List<T> select(T entity) {
        return mapper.select(entity);
    }

    @Override
    public PageInfo<T> selectPage(PageVo vo, T entity) throws Exception {
        PageHelper.startPage(vo.getPage(), vo.getLimit(), processOrderBy(vo.getSort()));
        List<T> list = mapper.select(entity);
        return new PageInfo<T>(list);
    }

    private String processOrderBy(String sort) {
        if (StringUtils.isEmpty(sort)) {
            return null;
        }
        String[] split = sort.split("\\s+");
        String cloumn = columnMapping.get(split[0]);
        if (StringUtils.isEmpty(cloumn)) {
            return null;
        }
        return cloumn + sort.substring(split[0].length());
    }

    @Override
    public List<T> selectAll() {
        return mapper.selectAll();
    }

    @Override
    public int selectCount(T entity) {
        return mapper.selectCount(entity);
    }

    @Override
    @Transactional
    public int insert(T entity) {
        EntityUtils.setCreateInfo(entity);
        return mapper.insert(entity);
    }

    @Override
    @Transactional
    public int update(T entity) {
        EntityUtils.setUpdateInfo(entity);
        return mapper.update(entity);
    }

    @Override
    @Transactional
    public int delete(T entity) {
        return mapper.delete(entity);
    }

    @Override
    @Transactional
    public int deleteById(Long id) {
        return mapper.deleteById(id);
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        // 根据mapper类型获取当前类的映射关系 AopProxyUtils.proxiedUserInterfaces(mapper)[0].getName() 获取当前代理mapper的全限定名
        Configuration configuration = sqlSessionFactory.getConfiguration();
        ResultMap resultMap =
            configuration.getResultMap(AopProxyUtils.proxiedUserInterfaces(mapper)[0].getName() + ".BaseResultMap");
        List<ResultMapping> mappings = resultMap.getResultMappings();
        for (ResultMapping a : mappings) {
            columnMapping.put(a.getProperty(), a.getColumn());
        }
    }
}
